package com.lingjtx.common.influx.client;

import com.lingjtx.common.influx.common.LineProtocolBuilder;
import com.lingjtx.common.influx.config.InfluxProperties;
import com.lingjtx.common.influx.ql.QLRequest;
import com.lingjtx.common.influx.ql.QLResponse;
import com.lingjtx.common.influx.ql.QLSeries;
import com.lingjtx.common.influx.ql.QLTable;
import com.lingjtx.common.other.http.Call;
import com.lingjtx.common.other.http.Callback;
import com.lingjtx.common.other.http.Network;
import com.lingjtx.common.thread.pooling.ObjectPoolTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.net.http.HttpClient;
import java.util.List;
import java.util.Objects;

@Component
public class InfluxQueryExecutor {

    private static final Logger log = LoggerFactory.getLogger(InfluxQueryExecutor.class);

    private static final String PRECISION = "ms";

    private final ObjectPoolTemplate<HttpClient> httpObjectPoolTemplate;

    private final InfluxProperties properties;

    public InfluxQueryExecutor(ObjectPoolTemplate<HttpClient> httpObjectPoolTemplate, InfluxProperties properties) {
        this.httpObjectPoolTemplate = httpObjectPoolTemplate;
        this.properties = properties;
    }

    public List<QLSeries> query(String sql) {
        InfluxClientApi service = Network.remote(InfluxClientApi.class, httpObjectPoolTemplate);
        QLRequest request = new QLRequest();
        request.setDb(properties.getBucket());
        request.setQ(sql);
        request.setEpoch(PRECISION);
        Call<QLResponse> call = service.influxQL(properties.getUrl(), "Token " + properties.getToken(), properties.getOrg(), request);
        QLResponse result = call.execute();
        if (Objects.nonNull(result) && Objects.nonNull(result.getResults())) {
            QLTable table = result.getResults().getFirst();
            if (Objects.nonNull(table)) {
                if (Objects.nonNull(table.getSeries())) {
                    return table.getSeries();
                }
            }
        }
        return null;
    }

    public String queryFlux(String script) {
        InfluxClientApi service = Network.remote(InfluxClientApi.class, httpObjectPoolTemplate);
        Call<String> call = service.influxQueryFlux(properties.getUrl(),"Token " + properties.getToken(), properties.getOrg(), script);
        return call.execute();
    }

    public void write(Object model) {
        String line = LineProtocolBuilder.build(model);
        InfluxClientApi service = Network.remote(InfluxClientApi.class, httpObjectPoolTemplate);
        Call<String> call = service.influxWrite(properties.getUrl(),"Token " + properties.getToken(), properties.getOrg(), properties.getBucket(), PRECISION, line);
        call.enqueue(new Callback<>() {
            @Override
            public void onResponse(String s) {
                log.info("Influxdb 写入数据结果：{}", s);
            }

            @Override
            public void onFailure(String str) {
                log.error("Influxdb 写入数据失败：{}", str);
            }
        });
    }
}
